package com.hsmw.api.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hsmw.api.config.jwt.CurrentHsmwUserUtils;
import com.hsmw.api.config.jwt.LoginUser;
import com.hsmw.api.mapper.HsmwConstructionUnitMapper;
import com.hsmw.api.mapper.HsmwExamineRecordMapper;
import com.hsmw.api.mapper.HsmwItemMapper;
import com.hsmw.api.mapper.HsmwUserMapper;
import com.hsmw.api.vo.ConcreteItemCountVO;
import com.hsmw.api.vo.ItemCountTypeVO;
import com.hsmw.api.vo.ItemDetailInfoVO;
import com.hsmw.api.vo.ItemDetailVO;
import com.hsmw.common.base.BaseService;
import com.htn.common.core.base.DataResponse;
import com.htn.common.core.constant.AuditStatusEnum;
import com.htn.common.core.constant.CommonConstants;
import com.htn.common.core.constant.UserTypeEnum;
import com.htn.common.core.enums.ExamineTypeEnum;
import com.hsmw.api.utils.CommonUtils;
import com.htn.common.core.util.SendSmsUtil;
import com.hsmw.domain.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class HsmwItemService extends BaseService<HsmwItemMapper, HsmwItem> {

	@Autowired
	private HsmwItemMapper hsmwItemMapper;
	@Autowired
	private HsmwUserMapper hsmwUserMapper;
	@Autowired
	private HsmwConstructionUnitMapper hsmwConstructionUnitMapper;

	@Autowired
	private HsmwItemConcreteRelationService hsmwItemConcreteRelationService;


	@Autowired
	private CurrentHsmwUserUtils currentHsmwUserUtils;

	@Autowired
	private HsmwDriverNewsService hsmwDriverNewsService;


	@Autowired
	private HsmwExamineRecordMapper hsmwExamineRecordMapper;



	@Autowired
	private HsmwPmUserService hsmwPmUserService;


	@Value(value = "${sms.appKey}")
	private String appKey;
	@Value(value = "${sms.channel}")
	private String channel;
	@Value(value = "${sms.smsSign}")
	private String smsSign;
	@Value(value = "${sms.appId}")
	private int appId;
	@Value(value = "${sms.itemAuditFail}")
	private int itemAuditFail;
	@Value(value = "${sms.itemAuditSuccess}")
	private int itemAuditSuccess;

	public IPage<HsmwItem> getHsmwItemPage(IPage page, HsmwItem hsmwItem) {
		LambdaQueryWrapper<HsmwItem> queryWrapper = new LambdaQueryWrapper<>();
		if (!StrUtil.isEmpty(hsmwItem.getConstructionUnitId())) {
			queryWrapper.eq(HsmwItem::getConstructionUnitId, hsmwItem.getConstructionUnitId());
		}
		if (!StrUtil.isEmpty(hsmwItem.getName())) {
			queryWrapper.like(HsmwItem::getName, hsmwItem.getName());
		}
		IPage<HsmwItem> ipage = this.baseMapper.selectPage(page, queryWrapper.orderByDesc(HsmwItem::getCreateTime));
		return ipage;
	}

	public HsmwItem getHsmwItemById(String id) {
		LambdaQueryWrapper<HsmwItem> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(HsmwItem::getId, id);
		return hsmwItemMapper.selectOne(queryWrapper);
	}


	/**
	 * 新增或修改 逻辑删除
	 *
	 * @return
	 */
	public void saveOrUpdateHsmwItem(HsmwItem hsmwItem) {
		Integer result = 0;
		if (StringUtils.isNotBlank(hsmwItem.getId())) {
			List<HsmwUser> hsmwUserList = hsmwUserMapper.selectList(Wrappers.lambdaQuery(HsmwUser.class).eq(HsmwUser::getItemId, hsmwItem.getId()));
			hsmwUserList.forEach(hsmwUser -> {
				hsmwUser.setItemId("");
				hsmwUserMapper.updateById(hsmwUser);
			});
			List<HsmwUser> hsmwUsers = hsmwUserMapper.selectBatchIds(hsmwItem.getForceManIdList());
			hsmwUsers.forEach(hsmwUser -> {
				hsmwUser.setItemId(hsmwItem.getId());
				hsmwUserMapper.updateById(hsmwUser);
			});
			result = hsmwItemMapper.updateById(hsmwItem);
		} else {
			result = hsmwItemMapper.insert(hsmwItem);
			List<HsmwUser> hsmwUsers = hsmwUserMapper.selectBatchIds(hsmwItem.getForceManIdList());
			hsmwUsers.forEach(hsmwUser -> {
				hsmwUser.setItemId(hsmwItem.getId());
				hsmwUserMapper.updateById(hsmwUser);
			});
		}
	}


	/**
	 * 新增或修改项目信息
	 *
	 * @return
	 */
	public String saveOrUpdateHsmwItemInfo(HsmwItem hsmwItem) {
		Integer result = 0;
		LoginUser hsmwUser = currentHsmwUserUtils.getCurrentUserInfo();
		hsmwItem.setAuditStatus(AuditStatusEnum.UNRECEIVED.getValue());
		hsmwItem.setCreateUser(hsmwUser.getId());
		if (StringUtils.isNotBlank(hsmwItem.getId())) {
			HsmwItem items = hsmwItemMapper.selectById(hsmwItem.getId());
			hsmwItem.setUpdateTime(LocalDateTime.now());
			result = hsmwItemMapper.updateById(hsmwItem);
			return items.getItemIdentifyNum();
		} else {


			hsmwItem.setItemStatus(CommonConstants.NO);
			String identifyNum = CommonUtils.generateItemIdentifyNum();
			hsmwItem.setStartTime(LocalDate.now());
			hsmwItem.setItemIdentifyNum(identifyNum);
			String itemId = CommonUtils.generateId(hsmwItem);
			//SendSmsUtil.sendItemCode(appId,appKey,itemTemplateId,smsSign,hsmwUser.getUsername(),identifyNum);
			hsmwItem.setId(itemId);
			hsmwItemMapper.insert(hsmwItem);
			HsmwExamineRecord record = new HsmwExamineRecord();
			record.setAuditId(itemId);
			record.setAuditType(ExamineTypeEnum.TYPE_ITEM.getValue());
			record.setName(hsmwUser.getName());
			record.setUserId(hsmwUser.getId());
			record.setReadFlag(false);
			record.setMessage("有用户提交了名称为"+hsmwItem.getName()+"的项目");
			hsmwExamineRecordMapper.insert(record);
			return identifyNum;
		}
	}

	public IPage<HsmwItem> getItemAuditPageInfo(IPage page, HsmwItem hsmwItem) {

		IPage ipage = this.baseMapper.selectPagelist(page, hsmwItem);

		return ipage;
	}

	public DataResponse passHsmwAudit(HsmwItem hsmwItem) {
		HsmwItem item = hsmwItemMapper.selectById(hsmwItem.getId());
		//将项目的审核状态改为通过
		item.setAuditStatus(AuditStatusEnum.RECEIVED.getValue());
		item.setAuditSuccessTime(LocalDateTime.now());
		item.setRemark(hsmwItem.getRemark());
		hsmwItemMapper.updateById(item);
		// 获取项目的创建人信息 ，将项目的创建人 的用户类型置为PM
		HsmwPmUser pm = hsmwPmUserService.getById(item.getCreateUser());
		if(null== pm){
			return  DataResponse.failure(CommonConstants.ResponseStatus.VALIDATE_FAILED.getCode(),"项目的创建人不存在，该项目已经失效！");
		}
		if (UserTypeEnum.VISITOR.getValue().equals(pm.getType())){
			pm.setType(CommonConstants.UserRole.PM.name());
			//散户的项目ID设置为 散户专用项目
			pm.setItemId(CommonConstants.SANHU_ITEM);
			hsmwUserMapper.updateById(pm);
		}
		List<HsmwItemConcreteRelation> relations = hsmwItem.getRelations();
		hsmwItemConcreteRelationService.saveBatch(relations);

		//新增系统消息
		String msg = "您创建的项目已审核通过，可以邀请工长加入项目了，详情请点击himowang.com/sjd";
		HsmwDriverNews hsmwDriverNews = new HsmwDriverNews();
		hsmwDriverNews.setUserId(item.getCreateUser());
		hsmwDriverNews.setMessage(msg);
		hsmwDriverNews.setAlreadyRead("0");
		hsmwDriverNewsService.save(hsmwDriverNews);
		SendSmsUtil.sendBizOrderSmsCode(appId, appKey, msg,itemAuditSuccess, smsSign, pm.getUsername());

		return new DataResponse();
	}

	public DataResponse refuseHsmwAudit(String id, String remark) {
		try {
			HsmwItem item = hsmwItemMapper.selectById(id);
			//将项目的审核状态改为 审核失败
			item.setAuditStatus(AuditStatusEnum.FAILED.getValue());
			item.setRemark(remark);
			hsmwItemMapper.updateById(item);
			//新增系统消息
			HsmwPmUser pm = hsmwPmUserService.getById(item.getCreateUser());
			String msg = "您创建的项目审核失败，具体原因请点击查看himowang.com/sjd";
			HsmwDriverNews hsmwDriverNews = new HsmwDriverNews();
			hsmwDriverNews.setUserId(item.getCreateUser());
			hsmwDriverNews.setMessage(msg);
			hsmwDriverNews.setAlreadyRead("0");
			hsmwDriverNewsService.save(hsmwDriverNews);
			SendSmsUtil.sendBizOrderSmsCode(appId, appKey, msg,itemAuditFail, smsSign, pm.getUsername());

			return new DataResponse();
		}catch (Exception e){
			return  DataResponse.failure(CommonConstants.ResponseStatus.VALIDATE_FAILED.getCode(),"项目审核拒绝失败，请稍后重试！");
		}
	}

	public ItemDetailInfoVO getItemDetail(String key) {
		ItemDetailInfoVO itemDetailInfoVO = hsmwItemMapper.getItemDetail(key);
		return itemDetailInfoVO;
	}

	public boolean checkIfHasOrder(HashMap param) {
		int count  = hsmwItemMapper.checkIfHasOrder(param);
		if(count >0){
			return true;
		}else {
			return false;
		}
	}

	public IPage  selectItemInfoList( IPage page,HsmwItem  hsmwItem) {
		IPage page1= hsmwItemMapper.selectItemInfoList(page,hsmwItem);
		return page1;
	}

	public IPage  selectItemInfoListByForemanId( IPage page,String  userId) {
		IPage page1= hsmwItemMapper.selectItemListByForemanId(page,userId);
		return page1;
	}

	public void removeItemInfoById(String itemId) {
		hsmwItemMapper.removeItemInfoById(itemId);
	}

	public HashMap getItemDetailById(String itemId) {
		HsmwHtnUser currentUser = currentHsmwUserUtils.getCurrentHtnUserInfo();
		HashMap param = new HashMap();
		param.put("itemId",itemId);
		param.put("userId",currentUser.getId());
		ItemDetailVO itemDetailInfoVO = hsmwItemMapper.getItemDetailById(param);
		HashMap result = new HashMap();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM");
		LocalDate localDate = LocalDate.now().plusMonths(1);
		LocalDate beginDate = LocalDate.now().minusMonths(11);
		System.out.println(formatter.format(localDate));
		System.out.println(formatter.format(beginDate));
		List<ConcreteItemCountVO> monthRes =new ArrayList<>();
		for (int i=0;i<12;i++ ){
			ConcreteItemCountVO concreteItemCountVO =new ConcreteItemCountVO();
			concreteItemCountVO.setMonthValue(formatter.format(beginDate.plusMonths(i)));
			monthRes.add(concreteItemCountVO);
		}
		//具体的计算 需要 传当月的第一天
		param.put("beginDate",formatter.format(beginDate)+"-01");
		param.put("endDate",formatter.format(localDate)+"-01");
		List<ConcreteItemCountVO> monthList = hsmwItemMapper.selectItemMonthCount(param);
		for(ConcreteItemCountVO vo : monthRes){
			for(ConcreteItemCountVO vv :monthList){
				if (vo.getMonthValue().equals(vv.getMonthValue())){
					vo.setOrderCount(vv.getOrderCount());
					vo.setVolumeSum(vv.getVolumeSum());
					vo.setItemId(vv.getItemId());
					vo.setVehicleCount(vv.getVehicleCount());
				}
			}
		}
		sortObjectList(monthList);
		result.put("monthList",monthRes);
		result.put("monthMaxValue", CollectionUtil.isNotEmpty(monthList) ? monthList.get(0).getVolumeSum():0.00);

		//
		DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd");
		LocalDate dayBeginDate = LocalDate.now().minusDays(30);
		LocalDate endDate = LocalDate.now().plusDays(1);
		param.put("beginDate",format.format(dayBeginDate));
		param.put("endDate",format.format(endDate));
		List<ConcreteItemCountVO> dayList = hsmwItemMapper.selectItemDayCount(param);
		List<ConcreteItemCountVO> dayListRes = new ArrayList<>();
		for(int i=0;i<=30;i++){
			ConcreteItemCountVO concreteItemCountVO =new ConcreteItemCountVO();
			concreteItemCountVO.setDayValue(format.format(dayBeginDate.plusDays(i)));
			dayListRes.add(concreteItemCountVO);
		}
		for(ConcreteItemCountVO vo : dayListRes){
			for(ConcreteItemCountVO vv :dayList){
				if (vo.getDayValue().equals(vv.getDayValue())){
					vo.setOrderCount(vv.getOrderCount());
					vo.setVolumeSum(vv.getVolumeSum());
					vo.setItemId(vv.getItemId());
					vo.setVehicleCount(vv.getVehicleCount());
				}
			}
		}
		sortObjectList(dayList);
		result.put("dayList",dayListRes);
		result.put("dayMaxValue",CollectionUtil.isNotEmpty(dayList) ? dayList.get(0).getVolumeSum():0.00);
		result.put("itemDetail",itemDetailInfoVO);
		HsmwItem item = getHsmwItemById(itemId);
		result.put("companyName",item.getVehicleUnitName());
		if(com.htn.common.core.utils.StringUtils.isNotBlank(item.getVehicleUnitId()) && item.getVehicleUnitId().equals(currentUser.getOwnCompanyId())){
			result.put("flag",1);
		}else {
			result.put("flag",0);
		}
		return result;
	}

	public HashMap getItemStatisticsByItemId(ItemCountTypeVO itemCountTypeVO) {
		HashMap result = new HashMap();
		HashMap param = new HashMap();
		param.put("itemId",itemCountTypeVO.getItemId());
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM");
		if(itemCountTypeVO.getType().equals("month")){
			LocalDate localDate = LocalDate.now().plusMonths(1);
			LocalDate beginDate = LocalDate.now().minusMonths(11);
			System.out.println(formatter.format(localDate));
			System.out.println(formatter.format(beginDate));
			List<String> monthStrings = new ArrayList<>();
			for (int i=0;i<12;i++ ){
				monthStrings.add(formatter.format(beginDate.plusMonths(i)));
			}
			System.out.println(monthStrings);
			//具体的计算 需要 传当月的第一天
			param.put("beginDate",formatter.format(beginDate)+"-01");
			param.put("endDate",formatter.format(localDate)+"-01");
			List<ConcreteItemCountVO> monthList = hsmwItemMapper.selectItemMonthCount(param);
			result.put("monthBetween",monthStrings);
			result.put("monthValues",monthList);
			sortObjectList(monthList);
			result.put("maxValue",monthList.get(0).getVolumeSum());



		}else{
			DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy/MM/dd");
			LocalDate beginDate = LocalDate.now().minusDays(30);
			LocalDate endDate = LocalDate.now().plusDays(1);
			param.put("beginDate",format.format(beginDate));
			param.put("endDate",format.format(endDate));
			List<ConcreteItemCountVO> dayList = hsmwItemMapper.selectItemDayCount(param);
			result.put("dayList",dayList);
			List<String >  dayBetween = new ArrayList<>();
			for(int i=0;i<=30;i++){
				dayBetween.add(format.format(beginDate.plusDays(i)));
			}
			sortObjectList(dayList);
			result.put("dayBetween",dayBetween);
			result.put("maxValue",dayList.get(0).getVolumeSum());

		}

		return result;

	}

	public static void main(String[] args) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
		LocalDate localDate = LocalDate.now().plusMonths(1);
		LocalDate beginDate = LocalDate.now().minusMonths(11);
		System.out.println(formatter.format(localDate));
		System.out.println(formatter.format(beginDate));
	}

	private void sortObjectList(List<ConcreteItemCountVO > listOut) {
		Collections.sort(listOut, new Comparator<ConcreteItemCountVO>() {
			@Override
			public int compare(ConcreteItemCountVO o1, ConcreteItemCountVO o2) {
				return o2.getVolumeSum().compareTo(o1.getVolumeSum());//降序
			}
		});
	}

	public boolean checkItemIfExists(String itemId) {
		List<HsmwItem> items  = hsmwItemMapper.checkItemIfExists(itemId);
		if(CollectionUtil.isNotEmpty(items)){
			HsmwItem item = items.get(0);
			if(StringUtils.isNotBlank(item.getVehicleUnitId())){
				return true;
			}else {
				return false;
			}
		}else {
			return  false;
		}
	}

	public double sumDriverVolumeByItemId(String id) {
		return hsmwItemMapper.sumDriverVolumeByItemId(id);
	}
}
